<template>
  <view class="uni-filter-dropdown">
    <view class="dropdown-btn" @click="onDropdown">
      <view class="icon-select" :class="{ active: canReset }" v-if="isSelect || isRange"></view>
      <view class="icon-search" :class="{ active: canReset }" v-if="isSearch">
        <view class="icon-search-0"></view>
        <view class="icon-search-1"></view>
      </view>
      <view class="icon-calendar" :class="{ active: canReset }" v-if="isDate">
        <view class="icon-calendar-0"></view>
        <view class="icon-calendar-1"></view>
      </view>
    </view>
    <view class="uni-dropdown-cover" v-if="isOpened" @click="handleClose"></view>
    <view class="dropdown-popup dropdown-popup-right" v-if="isOpened" @click.stop>
      <!-- select-->
      <view v-if="isSelect" class="list">
        <label class="flex-r a-i-c list-item" v-for="(item, index) in dataList" :key="index" @click="onItemClick($event, index)">
          <check-box class="check" :checked="item.checked" />
          <view class="checklist-content">
            <text class="checklist-text" :style="item.styleIconText">{{ item[map.text] }}</text>
          </view>
        </label>
      </view>
      <view v-if="isSelect" class="flex-r opera-area">
        <view class="flex-f btn btn-default" :class="{ disable: !canReset }" @click="handleSelectReset"> {{ resource.reset }}</view>
        <view class="flex-f btn btn-submit" @click="handleSelectSubmit">{{ resource.submit }}</view>
      </view>
      <!-- search -->
      <view v-if="isSearch" class="search-area">
        <input class="search-input" v-model="filterValue" />
      </view>
      <view v-if="isSearch" class="flex-r opera-area">
        <view class="flex-f btn btn-submit" @click="handleSearchSubmit">{{ resource.search }}</view>
        <view class="flex-f btn btn-default" :class="{ disable: !canReset }" @click="handleSearchReset"> {{ resource.reset }}</view>
      </view>
      <!-- range -->
      <view v-if="isRange">
        <view class="input-label">{{ resource.gt }}</view>
        <input class="input" v-model="gtValue" />
        <view class="input-label">{{ resource.lt }}</view>
        <input class="input" v-model="ltValue" />
      </view>
      <view v-if="isRange" class="flex-r opera-area">
        <view class="flex-f btn btn-default" :class="{ disable: !canReset }" @click="handleRangeReset"> {{ resource.reset }}</view>
        <view class="flex-f btn btn-submit" @click="handleRangeSubmit">{{ resource.submit }}</view>
      </view>
      <!-- date -->
      <view v-if="isDate">
        <uni-datetime-picker ref="datetimepicker" :value="dateRange" type="datetimerange" return-type="timestamp" @change="datetimechange" @maskClick="timepickerclose">
          <view></view>
        </uni-datetime-picker>
      </view>
    </view>
  </view>
</template>

<script lang="ts">
import checkBox from "../uni-tr/table-checkbox.vue";

const resource = {
  reset: "重置",
  search: "搜索",
  submit: "确定",
  filter: "筛选",
  gt: "大于等于",
  lt: "小于等于",
  date: "日期范围",
};

const DropdownType = {
  Select: "select",
  Search: "search",
  Range: "range",
  Date: "date",
  Timestamp: "timestamp",
};

export default {
  name: "FilterDropdown",
  emits: ["change"],
  components: {
    checkBox,
  },
  options: {
    virtualHost: true,
  },
  props: {
    filterType: {
      type: String,
      default: DropdownType.Select,
    },
    filterData: {
      type: Array,
      default() {
        return [];
      },
    },
    mode: {
      type: String,
      default: "default",
    },
    map: {
      type: Object,
      default() {
        return {
          text: "text",
          value: "value",
        };
      },
    },
    filterDefaultValue: {
      type: [Array, String],
      default() {
        return "";
      },
    },
  },
  computed: {
    canReset() {
      if (this.isSearch) {
        return this.filterValue.length > 0;
      }
      if (this.isSelect) {
        return this.checkedValues.length > 0;
      }
      if (this.isRange) {
        return this.gtValue.length > 0 && this.ltValue.length > 0;
      }
      if (this.isDate) {
        return this.dateSelect.length > 0;
      }
      return false;
    },
    isSelect() {
      return this.filterType === DropdownType.Select;
    },
    isSearch() {
      return this.filterType === DropdownType.Search;
    },
    isRange() {
      return this.filterType === DropdownType.Range;
    },
    isDate() {
      return this.filterType === DropdownType.Date || this.filterType === DropdownType.Timestamp;
    },
  },
  watch: {
    filterData(newVal) {
      this._copyFilters();
    },
    indeterminate(newVal) {
      this.isIndeterminate = newVal;
    },
  },
  data() {
    return {
      resource,
      enabled: true,
      isOpened: false,
      dataList: [],
      filterValue: this.filterDefaultValue,
      checkedValues: [],
      gtValue: "",
      ltValue: "",
      dateRange: [],
      dateSelect: [],
    };
  },
  created() {
    this._copyFilters();
  },
  methods: {
    _copyFilters() {
      let dl = JSON.parse(JSON.stringify(this.filterData));
      for (let i = 0; i < dl.length; i++) {
        if (dl[i].checked === undefined) {
          dl[i].checked = false;
        }
      }
      this.dataList = dl;
    },
    openPopup() {
      this.isOpened = true;
      if (this.isDate) {
        this.$nextTick(() => {
          if (!this.dateRange.length) {
            this.resetDate();
          }
          this.$refs.datetimepicker.show();
        });
      }
    },
    closePopup() {
      this.isOpened = false;
    },
    handleClose(e) {
      this.closePopup();
    },
    resetDate() {
      let date = new Date();
      let dateText = date.toISOString().split("T")[0];
      this.dateRange = [dateText + " 0:00:00", dateText + " 23:59:59"];
    },
    onDropdown(e) {
      this.openPopup();
    },
    onItemClick(e, index) {
      let items = this.dataList;
      let listItem = items[index];
      if (listItem.checked === undefined) {
        items[index].checked = true;
      } else {
        items[index].checked = !listItem.checked;
      }

      let checkvalues = [];
      for (let i = 0; i < items.length; i++) {
        const item = items[i];
        if (item.checked) {
          checkvalues.push(item.value);
        }
      }
      this.checkedValues = checkvalues;
    },
    datetimechange(e) {
      this.closePopup();
      this.dateRange = e;
      this.dateSelect = e;
      this.$emit("change", {
        filterType: this.filterType,
        filter: e,
      });
    },
    timepickerclose(e) {
      this.closePopup();
    },
    handleSelectSubmit() {
      this.closePopup();
      this.$emit("change", {
        filterType: this.filterType,
        filter: this.checkedValues,
      });
    },
    handleSelectReset() {
      if (!this.canReset) {
        return;
      }
      var items = this.dataList;
      for (let i = 0; i < items.length; i++) {
        let item = items[i];
        this.$set(item, "checked", false);
      }
      this.checkedValues = [];
      this.handleSelectSubmit();
    },
    handleSearchSubmit() {
      this.closePopup();
      this.$emit("change", {
        filterType: this.filterType,
        filter: this.filterValue,
      });
    },
    handleSearchReset() {
      if (!this.canReset) {
        return;
      }
      this.filterValue = "";
      this.handleSearchSubmit();
    },
    handleRangeSubmit(isReset) {
      this.closePopup();
      this.$emit("change", {
        filterType: this.filterType,
        filter: isReset === true ? [] : [parseInt(this.gtValue), parseInt(this.ltValue)],
      });
    },
    handleRangeReset() {
      if (!this.canReset) {
        return;
      }
      this.gtValue = "";
      this.ltValue = "";
      this.handleRangeSubmit(true);
    },
  },
};
</script>

<style lang="scss">
$uni-primary: #1890ff !default;

.flex-r {
  display: flex;
  flex-direction: row;
}

.flex-f {
  flex: 1;
}

.a-i-c {
  align-items: center;
}

.j-c-c {
  justify-content: center;
}

.icon-select {
  width: 14px;
  height: 16px;
  border: solid 6px transparent;
  border-top: solid 6px #ddd;
  border-bottom: none;
  background-color: #ddd;
  background-clip: content-box;
  box-sizing: border-box;
}

.icon-select.active {
  background-color: $uni-primary;
  border-top-color: $uni-primary;
}

.icon-search {
  width: 12px;
  height: 16px;
  position: relative;
}

.icon-search-0 {
  border: 2px solid #ddd;
  border-radius: 8px;
  width: 7px;
  height: 7px;
}

.icon-search-1 {
  position: absolute;
  top: 8px;
  right: 0;
  width: 1px;
  height: 7px;
  background-color: #ddd;
  transform: rotate(-45deg);
}

.icon-search.active .icon-search-0 {
  border-color: $uni-primary;
}

.icon-search.active .icon-search-1 {
  background-color: $uni-primary;
}

.icon-calendar {
  color: #ddd;
  width: 14px;
  height: 16px;
}

.icon-calendar-0 {
  height: 4px;
  margin-top: 3px;
  margin-bottom: 1px;
  background-color: #ddd;
  border-radius: 2px 2px 1px 1px;
  position: relative;
}
.icon-calendar-0:before,
.icon-calendar-0:after {
  content: "";
  position: absolute;
  top: -3px;
  width: 4px;
  height: 3px;
  border-radius: 1px;
  background-color: #ddd;
}
.icon-calendar-0:before {
  left: 2px;
}
.icon-calendar-0:after {
  right: 2px;
}

.icon-calendar-1 {
  height: 9px;
  background-color: #ddd;
  border-radius: 1px 1px 2px 2px;
}

.icon-calendar.active {
  color: $uni-primary;
}

.icon-calendar.active .icon-calendar-0,
.icon-calendar.active .icon-calendar-1,
.icon-calendar.active .icon-calendar-0:before,
.icon-calendar.active .icon-calendar-0:after {
  background-color: $uni-primary;
}

.uni-filter-dropdown {
  position: relative;
  font-weight: normal;
}

.dropdown-popup {
  position: absolute;
  top: 100%;
  background-color: #fff;
  box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d;
  min-width: 150px;
  z-index: 1000;
}

.dropdown-popup-left {
  left: 0;
}

.dropdown-popup-right {
  right: 0;
}

.uni-dropdown-cover {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: transparent;
  z-index: 100;
}

.list {
  margin-top: 5px;
  margin-bottom: 5px;
}

.list-item {
  padding: 5px 10px;
  text-align: left;
}

.list-item:hover {
  background-color: #f0f0f0;
}

.check {
  margin-right: 5px;
}

.search-area {
  padding: 10px;
}

.search-input {
  font-size: 12px;
  border: 1px solid #f0f0f0;
  border-radius: 3px;
  padding: 2px 5px;
  min-width: 150px;
  text-align: left;
}

.input-label {
  margin: 10px 10px 5px 10px;
  text-align: left;
}

.input {
  font-size: 12px;
  border: 1px solid #f0f0f0;
  border-radius: 3px;
  margin: 10px;
  padding: 2px 5px;
  min-width: 150px;
  text-align: left;
}

.opera-area {
  cursor: default;
  border-top: 1px solid #ddd;
  padding: 5px;
}

.opera-area .btn {
  font-size: 12px;
  border-radius: 3px;
  margin: 5px;
  padding: 4px 4px;
}

.btn-default {
  border: 1px solid #ddd;
}

.btn-default.disable {
  border-color: transparent;
}

.btn-submit {
  background-color: $uni-primary;
  color: #ffffff;
}
</style>
